﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Windows.Controls;

using AtletIS.Shared.Entities;
using AtletIS.Shared.Data.aDbDataSetTableAdapters;
using AtletIS.Shared.Helpers;
using AtletIS.Shared.Data;

namespace AtletIS.Shared.Forms
{
    public partial class frmSector : Form
    {
        public int code; // 3-vrhy, 4-dialka, 5-vyska

        private int nDataTableColumns = 0; // pocet stlpcov tabulky dtPerformances bez stlpcov vysok
        private DisciplineListEntity _discipline;

        private DisciplineListTableAdapter taDisciplineList = new DisciplineListTableAdapter();
        private PerformancesTableAdapter taPerformances = new PerformancesTableAdapter();
        private ExtTextsTableAdapter taExtTexts = new ExtTextsTableAdapter();
        private RefPointsTableAdapter taRefPoints = new RefPointsTableAdapter();
        private DataTable dtPerformances, dtExtTexts;

        private System.Timers.Timer countdownTimer;
        private int countdownMinSetting, countdownSecSetting, countdownMinChanging, countdownSecChanging;

        #region Ctor

        public frmSector(DisciplineListEntity discipline)
        {
            InitializeComponent();

            this._discipline = discipline;
            this.Icon = Properties.Resources.Sector64;
        }

        #endregion

        #region Events handlers

        // Form Load
        private void frmSector_Load(object sender, EventArgs e)
        {
            code = _discipline.DisciplineCode;

            #region Get performances

            dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(Globals.ActiveDiscipline.ID);
            dtPerformances.DefaultView.RowFilter = "Code = 0";
            dtPerformances.DefaultView.Sort = "Lane ASC, SB ASC, PB ASC, StartNumber ASC, Surname ASC";
            dtPerformances = dtPerformances.DefaultView.ToTable();
            dtPerformances.AcceptChanges();

            #endregion

            #region Title

            this.Text = string.Format("SECTOR :: {0} ({1})", Globals.ActiveDiscipline.Name, Globals.ActiveDiscipline.ID);
            this.tsslCount.Text = "Počet pretekárov: " + dtPerformances.Rows.Count.ToString();

            #endregion

            #region Status

            switch (_discipline.Status)
            {
                case 1:
                    tsmiNotStarted.Checked = true;
                    tsmiStarted.Checked = false;
                    tsmiFinished.Checked = false;
                    tsslStatus.Text = "Stav disciplíny: Pred začiatkom";
                    break;

                case 2:
                    tsmiNotStarted.Checked = false;
                    tsmiStarted.Checked = true;
                    tsmiFinished.Checked = false;
                    tsslStatus.Text = "Stav disciplíny: Prebiehajúca";
                    break;

                case 3:
                    tsmiNotStarted.Checked = false;
                    tsmiStarted.Checked = false;
                    tsmiFinished.Checked = true;
                    tsslStatus.Text = "Stav disciplíny: Ukončená";
                    break;
            }

            #endregion

            if (_discipline.DisciplineCode == Globals.ThrowsCode)
            {
                this.FillDisciplinesTypesForLaser();

                lblRef2.Visible = false;
                txtRef2.Visible = false;
                btnRef2.Visible = false;
            }
            else
            {
                cmbDiscipline.Enabled = false;
                cmbDiscipline.Items.Clear();
            }

            txtResult.Text = string.Empty;

            #region Create table header for 6-attempts disciplines

            if (code == Globals.ThrowsCode | code == Globals.HorJumpCode)
            {
                for (int i = 0; i < 6; i++)
                    { dtPerformances.Columns.Add((i + 1).ToString()); }

                // Create layout
                dgvResults.DataSource = dtPerformances;
                Helpers.DgvLayoutHelper.SixAttempsLayout(dgvResults);
                gbNext.Visible = false;
            }

            #endregion

            #region Create table header for HighJump / PoleVault

            if (code == Globals.VerJumpCode)
            {
                this.nDataTableColumns = this.dtPerformances.Columns.Count;

                if (!string.IsNullOrEmpty(_discipline.Params))
                {
                    foreach (string str in _discipline.Params.Split(','))
                        dtPerformances.Columns.Add(str);
                }
                
                // Create layout
                dgvResults.DataSource = null;
                dgvResults.DataSource = dtPerformances;
                Helpers.DgvLayoutHelper.MultiAttemptsLayout(dgvResults, _discipline.Params);
                gbNext.Visible = true;
            }

            #endregion

            #region Read ext.texts

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                foreach (DataRow dr in dtPerformances.Rows)
                {
                    int performanceId = Convert.ToInt32(dr["ID"]);

                    dtExtTexts = DatabaseHelper.GetExtTextsByPerformanceIdActive(performanceId);

                    if (code == Globals.VerJumpCode)
                    {
                        foreach (string s in _discipline.Params.Split(','))
                        {
                            string filter = string.Format("Header = '{0}' AND Active = 1", s);
                            
                            if (dtExtTexts.Select(filter).Count() > 0)
                                dr[s] = dtExtTexts.Select(filter)[0]["Text1"].ToString();
                        }
                    }
                    else
                    {
                        for (int i = 1; i <= 6; i++)
                        {
                            string filter = string.Format("Header = '{0}' AND Active = 1", i.ToString());
                            
                            if (dtExtTexts.Select(filter).Count() > 0)
                                dr[i.ToString()] = dtExtTexts.Select(filter)[0]["Text1"].ToString();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace, "Sector", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

            #endregion

            this.rbMin1_CheckedChanged(null, null);

            this.SetDefaultCell();

            this.GetRefPoint(1);
            this.GetRefPoint(2);
        }

        // Cell end edit
        private void dgvResults_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            string cellValue = string.Empty, headerValue, performanceId;

            try
            {
                if (this.dgvResults.CurrentCell != null && this.dgvResults.CurrentCell.Value != null)
                    cellValue = dgvResults.CurrentCell.Value.ToString();

                headerValue = dgvResults.Columns[dgvResults.CurrentCell.ColumnIndex].Name.ToString();
                performanceId = dgvResults.Rows[dgvResults.CurrentCell.RowIndex].Cells["ID"].Value.ToString();

                if (!ExtTextsHelper.ValidateExtText(cellValue))
                {
                    MessageBox.Show("Zadali ste neplatnú hodnotu.", "Sector");
                    return;
                }

                aDbDataSet.ExtTextsDataTable dtExtTexts = DatabaseHelper.GetExtTextsByPerformanceIdHeaderAll(Convert.ToInt32(performanceId), headerValue);

                #region Insert ext. text

                if (dtExtTexts.Rows.Count == 0)
                {
                    if (!string.IsNullOrEmpty(cellValue))
                    {
                        aDbDataSet.PerformancesRow performancesRow = (aDbDataSet.PerformancesRow)DatabaseHelper.GetPerformancesById(Convert.ToInt32(performanceId)).Rows[0];
                        aDbDataSet.ExtTextsCodesRow extTextsCodesRow = (aDbDataSet.ExtTextsCodesRow)DatabaseHelper.GetExtTextsCodesById(1).Rows[0];
                        
                        dtExtTexts.AddExtTextsRow(performancesRow, null, headerValue, 
                            Num1: 0, Num2: 0, Text1: cellValue, Text2: null,
                            WebId: 0, Active: true, Sync: false, Modified: DateTime.Now, parentExtTextsCodesRowByFK_ExtTexts_ExtTextsCodes: extTextsCodesRow, VersionInfo: null);
                    }
                    else
                    {
                        dgvResults.CurrentCell.Value = DBNull.Value;
                    }
                }

                #endregion

                #region Update ext. text

                if (dtExtTexts.Rows.Count == 1)
                {
                    if (!string.IsNullOrEmpty(cellValue))
                    {
                        dtExtTexts.Rows[0]["Active"] = true;
                        dtExtTexts.Rows[0]["Text1"] = cellValue;
                    }
                    else
                    {
                        dtExtTexts.Rows[0]["Active"] = false;
                        dtExtTexts.Rows[0]["Text1"] = DBNull.Value;

                        dgvResults.CurrentCell.Value = DBNull.Value;
                    }

                    dtExtTexts.Rows[0]["Modified"] = DateTime.Now;
                    taExtTexts.Update(dtExtTexts.Rows[0]);
                }

                #endregion

                // Update Performances
                ExtTextsHelper.UpdatePerformances(_discipline);
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Cell enter
        private void dgvResults_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            this.ResetCountdownToSetting();
            this.SetActiveAttempt();
        }

        private void dgvResults_SelectionChanged(object sender, EventArgs e)
        {
            this.SetDefaultCell();
        }

        private void SetDefaultCell()
        {
            try
            {
                if (_discipline.DisciplineCode == Globals.ThrowsCode || _discipline.DisciplineCode == Globals.HorJumpCode)
                {
                    var columnName = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].Name;
                    if (columnName == "StartNumber" | columnName == "Surname" | columnName == "FirstName")
                    {
                        this.dgvResults.CurrentCell = this.dgvResults["1", 0];
                    }
                }
            }
            catch { }
        }

        /// <summary>
        /// Nastavi aktualny pokus na discipline (ActivePerformanceId, ActivePerformanceHeader).
        /// </summary>
        private void SetActiveAttempt()
        {
            try
            {
                if (this.dgvResults.CurrentCell != null && this.dgvResults.CurrentRow != null)
                {
                    DataTable dt = DatabaseHelper.GetDisciplineListById(_discipline.ID);
                    dt.Rows[0]["ActivePerformanceId"] = ((DataRowView)this.dgvResults.CurrentRow.DataBoundItem)["ID"];
                    dt.Rows[0]["ActivePerformanceHeader"] = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;
                    dt.Rows[0]["Modified"] = DateTime.Now;
                    taDisciplineList.Update(dt.Rows[0]);
                }

            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region Menu buttons

        // Stav prebiehajuca
        private void tsmiStarted_Click(object sender, EventArgs e)
        {
            try
            {
                Helpers.StatusHelper.UpdateStatus(_discipline, 2);
                if (Globals.ActiveDiscipline != null)
                    Globals.ActiveDiscipline.Status = 2;
                
                tsmiNotStarted.Checked = false;
                tsmiStarted.Checked = true;
                tsmiFinished.Checked = false;
                tsslStatus.Text = "Stav disciplíny: Prebiehajúca";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }

        // Stav ukoncena
        private void tsmiFinished_Click(object sender, EventArgs e)
        {
            try
            {
                StatusHelper.UpdateStatus(_discipline, Globals.StatusFinished);
                if (Globals.ActiveDiscipline != null)
                    Globals.ActiveDiscipline.Status = Globals.StatusFinished;

                this.tsmiNotStarted.Checked = false;
                this.tsmiStarted.Checked = false;
                this.tsmiFinished.Checked = true;
                this.tsslStatus.Text = "Stav disciplíny: Ukončená";
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Optika
        private void tsmiOptika_Click(object sender, EventArgs e)
        {
            this.tsmiOptika.Checked = !this.tsmiOptika.Checked;
            this.gbOptics.Enabled = this.tsmiOptika.Checked;
        }

        // Tabula
        private void tsmiTabula_Click(object sender, EventArgs e)
        {
            this.tsmiTabula.Checked = !this.tsmiTabula.Checked;
            this.gbBoardSettings.Enabled = this.tsmiTabula.Checked;
            this.gbBoardActions.Enabled = this.tsmiTabula.Checked;
            this.gbBoardCountdown.Enabled = this.tsmiTabula.Checked;
        }

        // Povol finale
        private void tsbFinal_Click(object sender, EventArgs e)
        {
            if (_discipline.DisciplineCode == Globals.VerJumpCode)
                return;

            this.gbFinal.Visible = !this.gbFinal.Visible;
        }

        // Set DNS
        private void tsbDns_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Naozaj chcete nastaviť DNS a odstrániť pretekára zo zoznamu?", "DNS", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
                return;

            try
            {
                if (this.dgvResults.CurrentRow != null && this.dgvResults.CurrentRow.DataBoundItem is DataRowView)
                {
                    DataRow dr = ((DataRowView)this.dgvResults.CurrentRow.DataBoundItem).Row;
                    dr["Code"] = 4; // DNS
                    dr["Modified"] = DateTime.Now;
                    taPerformances.Update(dr);

                    // Reload form
                    frmSector_Load(null, null);
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Speaker
        private void tsbSpeaker_Click(object sender, EventArgs e)
        {
            frmSpeaker frm = new frmSpeaker(_discipline, null);
            frm.ShowDialog();
        }

        #endregion

        #region Postupove vysky

        // Prida vysku
        private void btnAddHeight_Click(object sender, EventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(txtHeight.Text.Trim()))
                {
                    this.dgvResults.Columns.Add(txtHeight.Text, txtHeight.Text);
                    this.dgvResults.Columns[txtHeight.Text].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                    this.txtHeight.Text = string.Empty;
                    this.UpdateNote();
                }
            }
            catch (Exception ex)
            {
                this.txtHeight.Text = string.Empty;
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Maze vysku
        private void btnRemoveHeight_Click(object sender, EventArgs e)
        {
            this.dgvResults.Columns.Remove(dgvResults.CurrentCell.OwningColumn);
            this.UpdateNote();
        }

        // Update Params on discipline
        private void UpdateNote()
        {
            // vyska
            if (code == Globals.VerJumpCode)
            {
                // Ulozi nazvy doplnenych stlpcov do poznamky discipliny
                string note = string.Empty;
                
                for (int i = this.nDataTableColumns; i < dgvResults.Columns.Count; i++)
                    note += dgvResults.Columns[i].Name.ToString() + ",";

                note = note.TrimEnd(',');

                DataTable dtDiscipline = DatabaseHelper.GetDisciplineListById(Globals.ActiveDiscipline.ID);
                if (dtDiscipline.Rows.Count == 1)
                {
                    dtDiscipline.Rows[0]["Params"] = note;
                    dtDiscipline.Rows[0]["Modified"] = DateTime.Now;
                    taDisciplineList.Update(dtDiscipline.Rows[0]);

                    Globals.ActiveDiscipline.Params = note;
                }
            }
        }

        #endregion

        #region Finale

        // Postup do finale
        private void btnFinal_Click(object sender, EventArgs e)
        {
            try
            {
                // Get actual Results
                DataTable dtActual = DatabaseHelper.GetPerformancesByDisciplineListId(Globals.ActiveDiscipline.ID);

                // Update Results in local table
                foreach (DataRow dr in this.dtPerformances.Rows)
                {
                    if (dtActual.Select("ID = " + dr["ID"]).Count() > 0)
                    {
                        dr["Code"] = dtActual.Select("ID = " + dr["ID"])[0]["Code"];
                        dr["Result"] = dtActual.Select("ID = " + dr["ID"])[0]["Result"];
                    }
                }

                this.dtPerformances.DefaultView.Sort = "Code ASC, Result DESC";
                this.dtPerformances = this.dtPerformances.DefaultView.ToTable();

                for (int i = this.dtPerformances.Rows.Count - 1; i >= Convert.ToInt32(nudFinal.Value); i--)
                {
                    dtPerformances.Rows[i].Delete();
                }

                this.dtPerformances.DefaultView.Sort = "Code ASC, Result ASC";
                this.dtPerformances = this.dtPerformances.DefaultView.ToTable();

                this.dgvResults.DataSource = null;
                this.dgvResults.DataSource = this.dtPerformances;
                Helpers.DgvLayoutHelper.SixAttempsLayout(this.dgvResults);

                gbFinal.Visible = false;
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region Optika

        private SerialPort spLaser;

        double pointX = 0, pointY = 0;
        double refX1 = 0, refY1 = 0, refX2 = 0, refY2 = 0;
        double disciplineOffset = 0;
        double vysledok = 0;

        // Pripojit opticke meranie
        private void btnOpticsConnect_Click(object sender, EventArgs e)
        {
            try
            {
                spLaser = new SerialPort("COM" + Convert.ToInt32(nudOpticsPort.Value).ToString(), 1200, Parity.Even, 7, StopBits.One);
                spLaser.DataReceived += new SerialDataReceivedEventHandler(LaserDataReceivedHandler);

                spLaser.Open();
                if (spLaser.IsOpen)
                {
                    txtOpticsStatus.Text = "OK";
                    txtOpticsStatus.BackColor = Color.Yellow;
                }
                else
                {
                    txtOpticsStatus.Text = "N/A";
                    txtOpticsStatus.BackColor = Color.Red;
                }
            }
            catch
            {
                txtOpticsStatus.Text = "N/A";
                txtOpticsStatus.BackColor = Color.Red;
            }
        }

        // LaserDataReceivedHandler
        private void LaserDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            if (sp.BytesToRead == 51)
            {
                vysledok = 0;

                string sOutput = sp.ReadExisting();

                // Straight distance
                string sSD = sOutput.Substring(2, 8);
                double SD = Convert.ToDouble(sSD) / 1000;

                // Vertical angle
                string sVaDeg = sOutput.Substring(11, 3);
                string sVaMin = sOutput.Substring(14, 2);
                string sVaSec = sOutput.Substring(16, 2);
                double VA = Convert.ToDouble(sVaDeg) + Convert.ToDouble(sVaMin) / 60 + Convert.ToDouble(sVaSec) / 3600;

                // Horizontal angle - skontrolovat indexy
                string sHaDeg = sOutput.Substring(19, 3);
                string sHaMin = sOutput.Substring(22, 2);
                string sHaSec = sOutput.Substring(24, 2);
                double HA = Convert.ToDouble(sHaDeg) + Convert.ToDouble(sHaMin) / 60 + Convert.ToDouble(sHaSec) / 3600;

                // Horizontal distance
                string sHD = sOutput.Substring(28, 8);
                double HD = Convert.ToDouble(sHD) / 1000;

                // Suradnice X, Y
                pointX = HD * Math.Cos(Math.PI * HA / 180);
                pointY = HD * Math.Sin(Math.PI * HA / 180);

                if (_discipline.DisciplineCode == Globals.ThrowsCode)
                {
                    // Vypocet pre hody
                    vysledok = Math.Sqrt(Math.Pow(refX1 - pointX, 2) + Math.Pow(refY1 - pointY, 2)) - disciplineOffset;
                }
                else if (_discipline.DisciplineCode == Globals.HorJumpCode)
                {
                    // Vypocet pre skoky
                    double c = 1;
                    double b = (1 / refX1 - 1 / refX2) / (-refY1 / refX1 + refY2 / refX2);
                    double a = (-b * refY1 - c) / refX1;
                    vysledok = Math.Abs(a * pointX + b * pointY + c) / Math.Sqrt(Math.Pow(a, 2) + Math.Pow(b, 2));
                }

                // Zaokruhlenie nadol
                vysledok = Math.Truncate(vysledok * 100) / 100;

                if (chkManualOffset.Checked)
                {
                    vysledok = vysledok + Convert.ToDouble(nudManualOffsetCm.Value / 100);
                }

                // Update GUI
                this.BeginInvoke(new EventHandler(UpdateDataFromLaser));
            }
        }

        // Updates grid and saves data
        private void UpdateDataFromLaser(Object sender, EventArgs e)
        {
            if (this.dgvResults.CurrentCell != null)
            {
                this.dgvResults.CurrentCell.Value = (vysledok * 100).ToString();
                this.txtResult.Text = vysledok.ToString("#,##0.00");

                // Zapise data do DB
                this.dgvResults_CellEndEdit(null, null);

                // Zobrazi data na tabuli
                this.btnBoardAfter_Click(null, null);
            }
        }

        // Ref. point #1
        private void btnRef1_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.pointX == 0 & this.pointY == 0)
                {
                    MessageBox.Show("Namerajte referenčný bod, prosím!", "Referenčný bod", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                this.refX1 = this.pointX;
                this.refY1 = this.pointY;

                this.txtRef1.Text = "OK";
                this.txtRef1.BackColor = Color.Yellow;

                this.dgvResults.CurrentCell.Value = DBNull.Value;

                this.SaveRefPoint(order: 1);

                MessageBox.Show("Referenčný bod #1 bol vytvorený!", "Referenčný bod", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Ref. point #2
        private void btnRef2_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.pointX == 0 & this.pointY == 0)
                {
                    MessageBox.Show("Namerajte referenčný bod, prosím!", "Referenčný bod", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                this.refX2 = this.pointX;
                this.refY2 = this.pointY;

                this.txtRef2.Text = "OK";
                this.txtRef2.BackColor = Color.Yellow;

                this.dgvResults.CurrentCell.Value = DBNull.Value;

                this.SaveRefPoint(order: 2);

                MessageBox.Show("Referenčný bod #2 bol vytvorený!", "Referenčný bod", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        // Zmena discipliny
        private void cmbDiscipline_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cmbDiscipline.SelectedValue == null)
                return;

            switch ((int)this.cmbDiscipline.SelectedValue)
            {
                case 1:
                case 4:
                    this.disciplineOffset = 2.135 / 2;
                    break;

                case 2:
                    this.disciplineOffset = 1.25;
                    break;

                case 3:
                    this.disciplineOffset = 8;
                    break;

                default:
                    this.disciplineOffset = 0;
                    break;
            }
        }

        // Manual offset
        private void chkManualOffset_CheckedChanged(object sender, EventArgs e)
        {
            this.nudManualOffsetCm.Enabled = this.chkManualOffset.Checked;
        }

        // Typy disciplin
        private void FillDisciplinesTypesForLaser()
        {
            this.cmbDiscipline.Enabled = true;

            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            for (int i = 0; i <= 3; i++)
                dt.Rows.Add();

            dt.Rows[0]["ID"] = 1;
            dt.Rows[0]["Name"] = "Vrh guľou";
            dt.Rows[1]["ID"] = 2;
            dt.Rows[1]["Name"] = "Hod diskom";
            dt.Rows[2]["ID"] = 3;
            dt.Rows[2]["Name"] = "Hod oštepom";
            dt.Rows[3]["ID"] = 4;
            dt.Rows[3]["Name"] = "Hod kladivom";

            this.cmbDiscipline.DataSource = dt;
            this.cmbDiscipline.SelectedIndex = -1;
        }

        private void GetRefPoint(int order)
        {
            aDbDataSet.RefPointsDataTable dtRefPoints = DatabaseHelper.GetRefPointsByDisciplineListId(_discipline.ID, order);

            if (dtRefPoints != null && dtRefPoints.Rows.Count == 1)
            {
                if (order == 1)
                {
                    this.refX1 = Convert.ToDouble(dtRefPoints.Rows[0]["RefPointX"]);
                    this.refY1 = Convert.ToDouble(dtRefPoints.Rows[0]["RefPointY"]);

                    this.txtRef1.Text = "OK";
                    this.txtRef1.BackColor = Color.Yellow;
                }

                if (order == 2)
                {
                    this.refX2 = Convert.ToDouble(dtRefPoints.Rows[0]["RefPointX"]);
                    this.refY2 = Convert.ToDouble(dtRefPoints.Rows[0]["RefPointY"]);

                    this.txtRef2.Text = "OK";
                    this.txtRef2.BackColor = Color.Yellow;
                }
            }
        }

        private void SaveRefPoint(int order)
        {
            aDbDataSet.RefPointsDataTable dtRefPoints = DatabaseHelper.GetRefPointsByDisciplineListId(_discipline.ID, order);

            if (dtRefPoints != null && dtRefPoints.Rows.Count == 1)
            {
                dtRefPoints.Rows[0]["RefPointX"] = this.pointX;
                dtRefPoints.Rows[0]["RefPointY"] = this.pointY;

                taRefPoints.Update(dtRefPoints.Rows[0]);
            }
            else
            {
                aDbDataSet.RefPointsRow drRefPoint = dtRefPoints.NewRefPointsRow();

                drRefPoint["DisciplineListId"] = _discipline.ID;
                drRefPoint["RefPointOrder"] = order;
                drRefPoint["RefPointX"] = this.pointX;
                drRefPoint["RefPointY"] = this.pointY;

                dtRefPoints.AddRefPointsRow(drRefPoint);
                taRefPoints.Update(dtRefPoints);
            }
        }

        #endregion

        #region Tabule

        // Pouzit rozhodcovsku tabulu
        private void chkBoardRef_CheckedChanged(object sender, EventArgs e)
        {
            this.nudBoardPortRef.Enabled = this.chkBoardRef.Checked;
        }

        // Pouzit divacku tabulu
        private void chkBoardFans_CheckedChanged(object sender, EventArgs e)
        {
            this.nudBoardPortFans.Enabled = this.chkBoardFans.Checked;
        }

        // Pred pokusom
        private void btnBoardBefore_Click(object sender, EventArgs e)
        {
            if (this.chkBoardRef.Checked || this.chkBoardFans.Checked)
            {
                #region Get data

                DataRowView currentRow = (DataRowView)this.dgvResults.CurrentRow.DataBoundItem;
                string startNumber = currentRow["StartNumber"].ToString();

                // Cell value
                string currentCellValue = string.Empty;
                if (this.dgvResults.CurrentCell != null && this.dgvResults.CurrentCell.Value != null)
                    currentCellValue = this.dgvResults.CurrentCell.Value.ToString();

                #endregion

                #region Referee board

                if (this.chkBoardRef.Checked)
                {
                    int portNumber = (int)this.nudBoardPortRef.Value;

                    if (_discipline.DisciplineCode == Globals.VerJumpCode)
                    {
                        string attempt = (currentCellValue.Length + 1).ToString();
                        string performance = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;

                        NumberScoreBoardHelper.SendDataPart(portNumber, startNumber, attempt, performance);
                    }
                    else
                    {
                        string attempt = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;
                        string performance = string.Empty;

                        NumberScoreBoardHelper.SendDataPart(portNumber, startNumber, attempt, performance);
                    }
                }

                #endregion

                #region Fans board

                if (this.chkBoardFans.Checked)
                {
                    string port = string.Format("COM{0}", this.nudBoardPortFans.Value);

                    TextScoreBoardHelper.Init(port);
                    TextScoreBoardHelper.ClearLine(111);
                    TextScoreBoardHelper.ClearLine(112);
                    TextScoreBoardHelper.ClearLine(113);
                    TextScoreBoardHelper.ClearLine(114);

                    string currentColumnName = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;

                    // Get rank, result from DB
                    int performanceId = Convert.ToInt32(currentRow["ID"]);
                    DataTable currentPerformance = DatabaseHelper.GetPerformancesById(performanceId);

                    string firstLine = string.Format("{0}   {1} {2}   {3}",
                            currentRow["StartNumber"].ToString(),
                            currentRow["Surname"].ToString().ToUpper(),
                            currentRow["FirstName"].ToString(),
                            currentRow["CountryId"].ToString());

                    string secondLine = string.Format("Rank: {0}     Performance: {1}",
                        currentPerformance.Rows[0]["Rank"].ToString(),
                        currentPerformance.Rows[0]["Result"].ToString().ToUpper());

                    string fourthLine = string.Format("Attempt: {0}       {1}       {2}",
                        currentCellValue.Length + 1,
                        currentColumnName,
                        currentCellValue);

                    TextScoreBoardHelper.WriteSimpleText(firstLine, 111);
                    TextScoreBoardHelper.WriteSimpleText(secondLine, 112);
                    TextScoreBoardHelper.WriteSimpleText(fourthLine, 114);
                    TextScoreBoardHelper.DeInit();
                }

                #endregion
            }
        }

        // Po pokuse
        private void btnBoardAfter_Click(object sender, EventArgs e)
        {
            if (this.chkBoardRef.Checked || this.chkBoardFans.Checked)
            {
                #region Get data

                DataRowView currentRow = (DataRowView)this.dgvResults.CurrentRow.DataBoundItem;
                string startNumber = currentRow["StartNumber"].ToString();

                // Cell value
                string currentCellValue = string.Empty;
                if (this.dgvResults.CurrentCell != null && this.dgvResults.CurrentCell.Value != null)
                    currentCellValue = this.dgvResults.CurrentCell.Value.ToString();

                #endregion

                #region Referee board

                if (this.chkBoardRef.Checked)
                {
                    int portNumber = (int)this.nudBoardPortRef.Value;

                    if (_discipline.DisciplineCode == Globals.VerJumpCode)
                    {
                        string attempt = (currentCellValue.Length).ToString();
                        string performance = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;

                        NumberScoreBoardHelper.SendDataPart(portNumber, startNumber, attempt, performance);
                    }
                    else
                    {
                        string attempt = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;
                        string performance = currentCellValue;

                        NumberScoreBoardHelper.SendDataPart(portNumber, startNumber, attempt, performance);
                    }
                }

                #endregion

                #region Fans board

                if (this.chkBoardFans.Checked)
                {
                    try
                    {
                        string port = string.Format("COM{0}", this.nudBoardPortFans.Value);
                        TextScoreBoardHelper.Init(port);
                        TextScoreBoardHelper.ClearLine(111);
                        TextScoreBoardHelper.ClearLine(112);
                        TextScoreBoardHelper.ClearLine(113);
                        TextScoreBoardHelper.ClearLine(114);

                        
                        string currentColumnName = this.dgvResults.Columns[this.dgvResults.CurrentCell.ColumnIndex].HeaderText;

                        // Get rank, result from DB
                        int performanceId = Convert.ToInt32(currentRow["ID"]);
                        DataTable currentPerformance = DatabaseHelper.GetPerformancesById(performanceId);

                        string firstLine = string.Format("{0}   {1} {2}   {3}",
                                currentRow["StartNumber"].ToString(),
                                currentRow["Surname"].ToString().ToUpper(),
                                currentRow["FirstName"].ToString(),
                                currentRow["CountryId"].ToString());

                        string secondLine = string.Format("Rank: {0}     Performance: {1}",
                            currentPerformance.Rows[0]["Rank"].ToString(),
                            currentPerformance.Rows[0]["Result"].ToString().ToUpper());

                        string fourthLine = string.Format("Attempt: {0}       {1}       {2}",
                            currentCellValue.Length,
                            currentColumnName,
                            currentCellValue);

                        TextScoreBoardHelper.WriteSimpleText(firstLine, 111);
                        TextScoreBoardHelper.WriteSimpleText(secondLine, 112);
                        TextScoreBoardHelper.WriteSimpleText(fourthLine, 114);
                        TextScoreBoardHelper.DeInit();
                    }
                    catch { }
                }

                #endregion
            }
        }

        // Zhasnut
        private void btnBoardOff_Click(object sender, EventArgs e)
        {
            // Rozhodcovska tabula
            if (this.chkBoardRef.Checked)
                NumberScoreBoardHelper.ClearDataPart((int)this.nudBoardPortRef.Value);

            // Divacka tabula
            if (this.chkBoardFans.Checked)
            {
                try
                {
                    string port = string.Format("COM{0}", this.nudBoardPortFans.Value);
                    TextScoreBoardHelper.Init(port);
                    TextScoreBoardHelper.ClearLine(111);
                    TextScoreBoardHelper.ClearLine(112);
                    TextScoreBoardHelper.ClearLine(113);
                    TextScoreBoardHelper.ClearLine(114);
                    TextScoreBoardHelper.DeInit();
                }
                catch { }
            }
        }

        // Odpocet
        private void btnBoardCounter_Click(object sender, EventArgs e)
        {
            try
            {
                if (chkBoardRef.Checked)
                {
                    this.countdownMinChanging = Convert.ToInt32(this.countdownMinSetting);
                    this.countdownSecChanging = Convert.ToInt32(this.countdownSecSetting);

                    NumberScoreBoardHelper.SendTimePart((int)this.nudBoardPortRef.Value, (byte)countdownMinChanging, (byte)countdownSecChanging);

                    this.countdownTimer = new System.Timers.Timer { AutoReset = false, Interval = 1000 };
                    this.countdownTimer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Tick);
                    this.countdownTimer.Start();
                }
                else
                    MessageBox.Show("Rozhodcovská tabuľa nie je nastavená.", "Odpočet");
            }
            catch (Exception ex) 
            { 
                Console.WriteLine(ex.Message); 
            }
        }

        // Zastavit odpocet
        private void btnClock_Click(object sender, EventArgs e)
        {
            if (chkBoardRef.Checked)
            {
                if (this.countdownTimer != null)
                    this.countdownTimer.Stop();

                this.ResetCountdownToSetting();
            }
            else
                MessageBox.Show("Rozhodcovská tabuľa nie je nastavená.", "Zastaviť odpočet");
        }

        // Info, treti riadok na divackej tabuli.
        private void btnBoardInfo_Click(object sender, EventArgs e)
        {
            if (this.chkBoardFans.Checked)
            {
                try
                {
                    string port = string.Format("COM{0}", this.nudBoardPortFans.Value);
                    TextScoreBoardHelper.Init(port);
                    TextScoreBoardHelper.ClearLine(113);
                    TextScoreBoardHelper.WriteSimpleText(this.txtBoardInfo.Text, 113);
                    TextScoreBoardHelper.DeInit();
                }
                catch { }
            }
            else
                MessageBox.Show("Divácka tabuľa nie je nastavená.", "Odpočet");
        }

        // Timer tick
        private void timer_Tick(object sender, EventArgs e)
        {
            if (this.countdownMinChanging >= 0 || this.countdownSecChanging >= 0)
            {
                if (countdownMinChanging == 0 && countdownSecChanging == 0)
                {
                    this.countdownTimer.Stop();
                    return;
                }
                else if (countdownMinChanging > 0 && countdownSecChanging == 0)
                {
                    countdownMinChanging -= 1;
                    countdownSecChanging = 59;
                }
                else
                {
                    countdownSecChanging -= 1;
                }

                this.BeginInvoke(new MethodInvoker(delegate 
                {
                    this.txtCountdown.Text = string.Format("{0:00}:{1:00}", countdownMinChanging, countdownSecChanging);
                }));

                NumberScoreBoardHelper.SendTimePart((int)this.nudBoardPortRef.Value, (byte)countdownMinChanging, (byte)countdownSecChanging);

                if (this.countdownTimer != null)
                    this.countdownTimer.Start();
            }
        }

        /// <summary>
        /// Reset odpoctu na pokus na tabuli.
        /// </summary>
        private void ResetCountdownToSetting()
        {
            if (chkBoardRef.Checked)
            {
                this.txtCountdown.Text = string.Format("{0:00}:{1:00}", this.countdownMinSetting, this.countdownSecSetting);
                NumberScoreBoardHelper.SendTimePart((int)this.nudBoardPortRef.Value, (byte)this.countdownMinSetting, (byte)this.countdownSecSetting);
            }
        }

        #endregion

        #region Tabule, cas odpoctu

        private void rbMin1_CheckedChanged(object sender, EventArgs e)
        {
            this.countdownMinSetting = 1;
            this.countdownSecSetting = 0;
            this.ResetCountdownToSetting();
        }

        private void rbMin15_CheckedChanged(object sender, EventArgs e)
        {
            this.countdownMinSetting = 1;
            this.countdownSecSetting = 30;
            this.ResetCountdownToSetting();
        }

        private void rbMin2_CheckedChanged(object sender, EventArgs e)
        {
            this.countdownMinSetting = 2;
            this.countdownSecSetting = 0;
            this.ResetCountdownToSetting();
        }

        private void rbMin3_CheckedChanged(object sender, EventArgs e)
        {
            this.countdownMinSetting = 3;
            this.countdownSecSetting = 0;
            this.ResetCountdownToSetting();
        }

        private void rbMin5_CheckedChanged(object sender, EventArgs e)
        {
            this.countdownMinSetting = 5;
            this.countdownSecSetting = 0;
            this.ResetCountdownToSetting();
        }

        #endregion

    }
}
